home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 19 / Mac Magazin and MacEasy Magazine CD - Issue 19.iso / Utilities / uae-0.4 / Source Code / memory.c < prev    next >
Text File  |  1996-02-13  |  10KB  |  452 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * Memory management
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11.  
  12. #include "config.h"
  13. #include "amiga.h"
  14. #include "options.h"
  15. #include "memory.h"
  16. #include "custom.h"
  17. #include "cia.h"
  18. #include "ersatz.h"
  19.  
  20. bool buserr;
  21.  
  22. const char romfile[] = "kick.rom"; 
  23.  
  24. lget_func do_lget[256];
  25. wget_func do_wget[256];
  26. bget_func do_bget[256];
  27. lput_func do_lput[256];
  28. wput_func do_wput[256];
  29. bput_func do_bput[256];
  30. xlate_func do_xlateaddr[256];
  31. check_func do_check[256];
  32.  
  33. /* Default memory access functions */
  34.  
  35. bool default_check(CPTR a, ULONG b)
  36. {
  37.     return false;
  38. }
  39.  
  40. UWORD *default_xlate(CPTR a)
  41. {
  42.     fprintf(stderr, "Your Amiga program just did something terribly stupid\n");
  43.     return 0;
  44. }
  45.  
  46. /* Chip memory */
  47.  
  48. static UWORD chipmemory[chipmem_size/2];
  49.  
  50. static ULONG chipmem_lget(CPTR) REGPARAM;
  51. static UWORD chipmem_wget(CPTR) REGPARAM;
  52. static UBYTE chipmem_bget(CPTR) REGPARAM;
  53. static void  chipmem_lput(CPTR, ULONG) REGPARAM;
  54. static void  chipmem_wput(CPTR, UWORD) REGPARAM;
  55. static void  chipmem_bput(CPTR, UBYTE) REGPARAM;
  56. static bool  chipmem_check(CPTR addr, ULONG size) REGPARAM;
  57. static UWORD *chipmem_xlate(CPTR addr) REGPARAM;
  58.  
  59. ULONG chipmem_lget(CPTR addr)
  60. {
  61.     addr -= chipmem_start & (chipmem_size-1);
  62.     addr &= chipmem_size-1;
  63.     return ((ULONG)chipmemory[addr >> 1] << 16) | chipmemory[(addr >> 1)+1];
  64. }
  65.  
  66. UWORD chipmem_wget(CPTR addr)
  67. {
  68.     addr -= chipmem_start & (chipmem_size-1);
  69.     addr &= chipmem_size-1;
  70.     return chipmemory[addr >> 1];
  71. }
  72.  
  73. UBYTE chipmem_bget(CPTR addr)
  74. {
  75.     addr -= chipmem_start & (chipmem_size-1);
  76.     addr &= chipmem_size-1;
  77.     return chipmemory[addr >> 1] >> (addr & 1 ? 0 : 8);
  78. }
  79.  
  80. void chipmem_lput(CPTR addr, ULONG l)
  81. {
  82.     addr -= chipmem_start & (chipmem_size-1);
  83.     addr &= chipmem_size-1;
  84.     chipmemory[addr >> 1] = l >> 16;
  85.     chipmemory[(addr >> 1)+1] = (UWORD)l;
  86. }
  87.  
  88. void chipmem_wput(CPTR addr, UWORD w)
  89. {
  90.     addr -= chipmem_start & (chipmem_size-1);
  91.     addr &= chipmem_size-1;
  92.     chipmemory[addr >> 1] = w;
  93. }
  94.  
  95. void chipmem_bput(CPTR addr, UBYTE b)
  96. {
  97.     addr -= chipmem_start & (chipmem_size-1);
  98.     addr &= chipmem_size-1;
  99.     if (!(addr & 1)) {
  100.     chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
  101.     } else {
  102.     chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff00) | b;
  103.     }
  104. }
  105.  
  106. bool chipmem_check(CPTR addr, ULONG size)
  107. {
  108.     addr -= chipmem_start & (chipmem_size-1);
  109.     addr &= chipmem_size-1;
  110.     return (addr + size) < chipmem_size;
  111. }
  112.  
  113. UWORD *chipmem_xlate(CPTR addr)
  114. {
  115.     addr -= chipmem_start & (chipmem_size-1);
  116.     addr &= chipmem_size-1;
  117.     return chipmemory + (addr >> 1);
  118. }
  119.  
  120. /* Slow memory */
  121.  
  122. static UWORD bogomemory[bogomem_size/2];
  123.  
  124. static ULONG bogomem_lget(CPTR) REGPARAM;
  125. static UWORD bogomem_wget(CPTR) REGPARAM;
  126. static UBYTE bogomem_bget(CPTR) REGPARAM;
  127. static void  bogomem_lput(CPTR, ULONG) REGPARAM;
  128. static void  bogomem_wput(CPTR, UWORD) REGPARAM;
  129. static void  bogomem_bput(CPTR, UBYTE) REGPARAM;
  130. static bool  bogomem_check(CPTR addr, ULONG size) REGPARAM;
  131. static UWORD *bogomem_xlate(CPTR addr) REGPARAM;
  132.  
  133. ULONG bogomem_lget(CPTR addr)
  134. {
  135.     addr -= bogomem_start & (bogomem_size-1);
  136.     addr &= bogomem_size-1;
  137.     return ((ULONG)bogomemory[addr >> 1] << 16) | bogomemory[(addr >> 1)+1];
  138. }
  139.  
  140. UWORD bogomem_wget(CPTR addr)
  141. {
  142.     addr -= bogomem_start & (bogomem_size-1);
  143.     addr &= bogomem_size-1;
  144.     return bogomemory[addr >> 1];
  145. }
  146.  
  147. UBYTE bogomem_bget(CPTR addr)
  148. {
  149.     addr -= bogomem_start & (bogomem_size-1);
  150.     addr &= bogomem_size-1;
  151.     return bogomemory[addr >> 1] >> (addr & 1 ? 0 : 8);
  152. }
  153.  
  154. void bogomem_lput(CPTR addr, ULONG l)
  155. {
  156.     addr -= bogomem_start & (bogomem_size-1);
  157.     addr &= bogomem_size-1;
  158.     bogomemory[addr >> 1] = l >> 16;
  159.     bogomemory[(addr >> 1)+1] = (UWORD)l;
  160. }
  161.  
  162. void bogomem_wput(CPTR addr, UWORD w)
  163. {
  164.     addr -= bogomem_start & (bogomem_size-1);
  165.     addr &= bogomem_size-1;
  166.     bogomemory[addr >> 1] = w;
  167. }
  168.  
  169. void bogomem_bput(CPTR addr, UBYTE b)
  170. {
  171.     addr -= bogomem_start & (bogomem_size-1);
  172.     addr &= bogomem_size-1;
  173.     if (!(addr & 1)) {
  174.     bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
  175.     } else {
  176.     bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff00) | b;
  177.     }
  178. }
  179.  
  180. bool bogomem_check(CPTR addr, ULONG size)
  181. {
  182.     addr -= bogomem_start & (bogomem_size-1);
  183.     addr &= bogomem_size-1;
  184.     return (addr + size) < bogomem_size;
  185. }
  186.  
  187. UWORD *bogomem_xlate(CPTR addr)
  188. {
  189.     addr -= bogomem_start & (bogomem_size-1);
  190.     addr &= bogomem_size-1;
  191.     return bogomemory + (addr >> 1);
  192. }
  193.  
  194. /* Kick memory */
  195.  
  196. static UWORD kickmemory[kickmem_size/2];
  197.  
  198. static ULONG kickmem_lget(CPTR) REGPARAM;
  199. static UWORD kickmem_wget(CPTR) REGPARAM;
  200. static UBYTE kickmem_bget(CPTR) REGPARAM;
  201. static void  kickmem_lput(CPTR, ULONG) REGPARAM;
  202. static void  kickmem_wput(CPTR, UWORD) REGPARAM;
  203. static void  kickmem_bput(CPTR, UBYTE) REGPARAM;
  204. static bool  kickmem_check(CPTR addr, ULONG size) REGPARAM;
  205. static UWORD *kickmem_xlate(CPTR addr) REGPARAM;
  206.  
  207. ULONG kickmem_lget(CPTR addr)
  208. {
  209.     addr -= kickmem_start & (kickmem_size-1);
  210.     addr &= kickmem_size-1;
  211.     return ((ULONG)kickmemory[addr >> 1] << 16) | kickmemory[(addr >> 1)+1];
  212. }
  213.  
  214. UWORD kickmem_wget(CPTR addr)
  215. {
  216.     addr -= kickmem_start & (kickmem_size-1);
  217.     addr &= kickmem_size-1;
  218.     return kickmemory[addr >> 1];
  219. }
  220.  
  221. UBYTE kickmem_bget(CPTR addr)
  222. {
  223.     addr -= kickmem_start & (kickmem_size-1);
  224.     addr &= kickmem_size-1;
  225.     return kickmemory[addr >> 1] >> (addr & 1 ? 0 : 8);
  226. }
  227.  
  228. void kickmem_lput(CPTR a, ULONG b)
  229. {
  230. }
  231.  
  232. void kickmem_wput(CPTR a, UWORD b)
  233. {
  234. }
  235.  
  236. void kickmem_bput(CPTR a, UBYTE b)
  237. {
  238. }
  239.  
  240. bool kickmem_check(CPTR addr, ULONG size)
  241. {
  242.     addr -= kickmem_start & (kickmem_size-1);
  243.     addr &= kickmem_size-1;
  244.     return (addr + size) < kickmem_size;
  245. }
  246.  
  247. UWORD *kickmem_xlate(CPTR addr)
  248. {
  249.     addr -= kickmem_start & (kickmem_size-1);
  250.     addr &= kickmem_size-1;
  251.     return kickmemory + (addr >> 1);
  252. }
  253.  
  254. static bool load_kickstart(void)
  255. {
  256.     int i;
  257.     ULONG cksum = 0, prevck = 0;
  258.     
  259.     FILE *f = fopen(romfile, "rb");
  260.     
  261.     if (f == NULL) {    
  262.         fprintf(stderr, "No Kickstart ROM found.\n");
  263.     return false;
  264.     }
  265.     
  266.     for(i = 0; i < kickmem_size/2; i++) {
  267.     unsigned char buffer[2];
  268.     if (fread(buffer, 1, 2, f) < 2) {
  269.         if (feof(f) && i == kickmem_size/4) {
  270.         fprintf(stderr, "Warning: Kickstart is only 256K.\n");
  271. #ifndef __mac__
  272.         memcpy (kickmemory + kickmem_size/4, kickmemory, kickmem_size/4);
  273. #else
  274.         memcpy (kickmemory + kickmem_size/4, kickmemory, kickmem_size/2);
  275. #endif
  276.         break;
  277.         } else {
  278.         fprintf(stderr, "Error while reading Kickstart.\n");
  279.         return false;
  280.         }
  281.     }
  282.     kickmemory[i] = buffer[0]*256 + buffer[1];
  283.     }
  284.     fclose (f);
  285.     
  286.     for (i = 0; i < kickmem_size/4; i++) {
  287.     ULONG data = kickmemory[i*2]*65536 + kickmemory[i*2+1];
  288.     cksum += data;
  289.     if (cksum < prevck)
  290.         cksum++;
  291.     prevck = cksum;
  292.     }
  293.     if (cksum != 0xFFFFFFFF) {
  294.     fprintf(stderr, "Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
  295.     }
  296.     return true;
  297. }
  298.  
  299. /* Address banks */
  300.  
  301. addrbank chipmem_bank = {
  302.     chipmem_lget, chipmem_wget, chipmem_bget,
  303.     chipmem_lput, chipmem_wput, chipmem_bput,
  304.     chipmem_xlate, chipmem_check
  305. };
  306.  
  307. addrbank bogomem_bank = {
  308.     bogomem_lget, bogomem_wget, bogomem_bget,
  309.     bogomem_lput, bogomem_wput, bogomem_bput,
  310.     bogomem_xlate, bogomem_check
  311. };
  312.  
  313. addrbank kickmem_bank = {
  314.     kickmem_lget, kickmem_wget, kickmem_bget,
  315.     kickmem_lput, kickmem_wput, kickmem_bput,
  316.     kickmem_xlate, kickmem_check
  317. };
  318.  
  319.  
  320. #ifdef DUALCPU
  321. ULONG mempattern;
  322. bool incpu;
  323. struct memreads {
  324.     CPTR addr;
  325.     ULONG value;
  326. } readlog[200];
  327.  
  328. int memlogptr = 0;
  329.  
  330. ULONG get_long(CPTR addr)
  331. {
  332.     ULONG result;
  333.     mempattern ^= addr ^ 0x99999999;
  334.     if (allowmem || !incpu) {
  335.         result = longget(addr);
  336.     if (incpu) {        
  337.         readlog[memlogptr].addr = addr;
  338.         readlog[memlogptr++].value = result;
  339.     }
  340.     } else {    
  341.     for(int i=0;i<memlogptr;i++) {
  342.         if (readlog[i].addr == addr) {
  343.         result = readlog[i].value;
  344.         }
  345.     }
  346.     }
  347.     return result;
  348. }
  349.  
  350. UWORD get_word(CPTR addr)
  351. {
  352.     UWORD result;
  353.     mempattern ^= addr ^ 0xAAAAAAAA;
  354.     if (allowmem || !incpu) {
  355.         result = wordget(addr);
  356.     if (incpu) {        
  357.         readlog[memlogptr].addr = addr;
  358.         readlog[memlogptr++].value = result;
  359.     }
  360.     } else {    
  361.     for(int i=0;i<memlogptr;i++) {
  362.         if (readlog[i].addr == addr) {
  363.         result = readlog[i].value;
  364.         }
  365.     }
  366.     }
  367.     return result;
  368. }
  369.  
  370. UBYTE get_byte(CPTR addr)
  371. {
  372.     UBYTE result;
  373.     mempattern ^= addr ^ 0x55555555;
  374.     if (allowmem || !incpu) {
  375.     result = byteget(addr);
  376.     if (incpu) {        
  377.         readlog[memlogptr].addr = addr;
  378.         readlog[memlogptr++].value = result;
  379.     }
  380.     } else {    
  381.     for(int i=0;i<memlogptr;i++) {
  382.         if (readlog[i].addr == addr) {
  383.         result = readlog[i].value;
  384.         }
  385.     }
  386.     }
  387.     return result;
  388. }
  389.  
  390. void put_long(CPTR addr, ULONG l)
  391. {
  392.     mempattern ^= addr ^ l ^ 0x09090909;
  393.     longput(addr,l);
  394. }
  395.  
  396. void put_word(CPTR addr, UWORD w)
  397. {
  398.     mempattern ^= addr ^ w ^ 0x0A0A0A0A;
  399.     wordput(addr,w);
  400. }
  401.  
  402. void put_byte(CPTR addr, UBYTE b)
  403. {
  404.     mempattern ^= addr ^ b ^ 0x05050505;
  405.     byteput(addr,b);
  406. }
  407.  
  408. #endif
  409.  
  410. void memory_init(void)
  411. {
  412. #ifdef DUALCPU
  413.     allowmem = true;
  414. #endif
  415.     buserr = false;
  416.     
  417.     map_banks(chipmem_bank, 0, 256);
  418.     
  419.     map_banks(custom_bank, 0xC0, 0x20);    
  420.  
  421.     if (use_slow_mem && bogomem_size > 0) {
  422.         map_banks(bogomem_bank, 0xC0, bogomem_size >> 16);
  423.     }
  424. #if 0
  425.     if (fastmem_size > 0)
  426.         map_banks(expmem_config_bank, 0xE8, 1);
  427. #endif
  428.     map_banks(kickmem_bank, 0xF8, 8);
  429.     map_banks(rtarea_bank, 0xF0, 1); rtarea_init ();
  430.     map_banks(cia_bank, 0xBF, 1);
  431.     map_banks(clock_bank, 0xDC, 1);
  432.  
  433.     if (!load_kickstart()) {
  434.     init_ersatz_rom(kickmemory);
  435.     }
  436. }
  437.  
  438. void map_banks(addrbank bank, int start, int size)
  439. {
  440.     int bnr;
  441.     for(bnr=start; bnr < start+size; bnr++) {
  442.     do_lget[bnr] = bank.lget;
  443.     do_wget[bnr] = bank.wget;
  444.     do_bget[bnr] = bank.bget;
  445.     do_lput[bnr] = bank.lput;
  446.     do_wput[bnr] = bank.wput;
  447.     do_bput[bnr] = bank.bput;
  448.     do_xlateaddr[bnr] = bank.xlateaddr;
  449.     do_check[bnr] = bank.check;
  450.     }
  451. }
  452.